package fr.machizaud.research.handlers;

import fr.machizaud.research.MalformedDocumentException;
import fr.machizaud.research.XMLHandler;
import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;

/**
 * User: Andréa
 * Date: 23/01/11
 * Time: 16:52
 * <p/>
 * Transform each attribute to child except metadata
 */
public class Attribute2Markup
        implements XMLHandler {
    private static final java.util.logging.Logger logger =
            java.util.logging.Logger.getLogger(Attribute2Markup.class.getCanonicalName());

    private static final Set<String> METADATAS = new HashSet<String>();

    private Attribute2Markup() {
    }

    private static class Attribute2MarkupHolder {
        private static final Attribute2Markup instance = new Attribute2Markup();
    }

    public static Attribute2Markup getInstance() {
        return Attribute2MarkupHolder.instance;
    }

    static {
        METADATAS.add("id");
        METADATAS.add("version");
    }

    @Override
    public void process(Document dom) throws MalformedDocumentException {
        logger.log(Level.INFO, "Handler {0}", getClass().getName());
        Element root = dom.getRootElement();

        transform(root);

        logger.log(Level.FINER, "Handler {0} : resulting dom {1}",
                new Object[]{
                        getClass(), dom
                }
        );
    }

    /**
     * Postfixe navigation
     *
     * @param node node being transformed
     */
    private void transform(Element node) {
        for (Object elementObject : node.getChildren()) {
            if (elementObject instanceof Element) {
                Element element = (Element) elementObject;
                transform(element);
            }
        }
        logger.log(Level.FINER, "Iterating node : {0}", node);
        List attributes = node.getAttributes();
        for (int i = 0; i < attributes.size();) {
            logger.log(Level.FINER, "Iterating attribute : {0}", attributes.get(i));
            if (attributes.get(i) instanceof Attribute) {
                Attribute attribute = (Attribute) attributes.get(i);
                //skiping metadata
                if (METADATAS.contains(attribute.getName())) {
                    //go to the next attributes
                    i++;
                    continue;
                }

                //removing it from attributes list
                attributes.remove(i);

                Element newChild = new Element(attribute.getName());
                newChild.setText(attribute.getValue());
                logger.log(Level.FINEST, "Built node : {0}", newChild);

                node.addContent(newChild);
            }
        }
        logger.log(Level.FINEST, "Resulting node : {0}", node);
    }
}
